package com.rules.admin.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.rules.admin.dao.SysUserDao;
import com.rules.admin.entity.RuleUserRole;
import com.rules.admin.entity.SysUser;
import com.rules.admin.entity.SysGroupUserRole;
import com.rules.admin.login.UserHolder;
import com.rules.admin.roleauthority.RoleauthorityMapper;
import com.rules.admin.roleauthority.model.RoleResource;
import com.rules.admin.service.*;
import com.rules.admin.utils.ResultUtils;
import com.rules.admin.vo.Role;
import com.rules.core.utils.RedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;

import com.rules.admin.vo.RuleUser;
import com.rules.admin.utils.Md5Util;

import java.util.*;

@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUser> implements SysUserService{
   @Autowired
   private UserHolder<RuleUser> userHolder;

   @Autowired
   private SysGroupUserRoleService sysGroupUserRoleService;
   @Autowired
   private RuleUserRoleService ruleUserRoleService;
   @Autowired
   private PermissionService permissionService;
   @Autowired
   private RedisUtils redisUtils;

   @Autowired
   private RoleauthorityService roleauthorityService;




   public SysUser insert(SysUser sysUser) throws Exception {
      sysUser.setPassword(Md5Util.md5Encode(sysUser.getUsername(), sysUser.getPassword()));
      this.save(sysUser);
      return sysUser;
   }

   public Map<String, Object> updateAccount(Map<String, Object> user) throws Exception {
      if (user.containsKey("newPassword")) {
         if (user.get("oldPassword") == "") {
            return ResultUtils.getFaildResultData(new String[]{"密码是必须的，请重新输入！"});
         } else {
            LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<SysUser>();
            wrapper.eq(SysUser::getUsername, user.get("username").toString());
            SysUser sysUser = (SysUser)this.getOne(wrapper);
            String password = sysUser.getPassword();
            if (!Md5Util.md5Encode(user.get("username").toString(), user.get("oldPassword").toString()).equals(password)) {
               return ResultUtils.getFaildResultData(new String[]{"旧密码输入错误，请重新输入！"});
            } else {
               sysUser.setPassword(Md5Util.md5Encode(user.get("username").toString(), user.get("newPassword").toString()));
               this.updateById(sysUser);
               return ResultUtils.getSuccessResultData();
            }
         }
      } else {
         String format = "\\w{2,15}[@][a-z0-9]{2,}[.]\\p{Lower}{2,}";
         if (!user.get("email").toString().matches(format)) {
            return ResultUtils.getFaildResultData(new String[]{"邮箱不合法，请重新输入！"});
         } else {
            LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<SysUser>();
            wrapper.eq(SysUser::getUsername, user.get("username").toString());
            SysUser sysUser = (SysUser)this.getOne(wrapper);
            sysUser.setEmail(user.get("email").toString());
            this.updateById(sysUser);
            return ResultUtils.getSuccessResultData();
         }
      }
   }

   public void delete(Long[] ids) {
      for(int i = 0; i < ids.length; ++i) {
         this.removeById(ids[i]);
         this.sysGroupUserRoleService.deleteByUserId(ids[i]);
      }
   }



   public IPage<SysUser> queryPage(String username, IPage<SysUser> page) {
      LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<SysUser>();
      if (StringUtils.isNotBlank(username)) {
         queryWrapper.like(SysUser::getUsername, "%" + username + "%");
      }
      return this.page(page, queryWrapper);
   }

   public SysUser findByUserName(String username) {
      if (StringUtils.isBlank(username)) {
         return null;
      } else {
         LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<SysUser>();
         queryWrapper.eq(SysUser::getUsername, username);
         return this.getOne(queryWrapper);
      }
   }

   public List<SysUser> getByGroupId(long groupId) {
      LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<SysUser>();
      List<SysGroupUserRole> sysGroupUserRoles = this.sysGroupUserRoleService.getByGroupId(groupId);
      List<Long> userIds = new ArrayList();
      if (sysGroupUserRoles.size() != 0) {
         for(int i = 0; i < sysGroupUserRoles.size(); ++i) {
            userIds.add(sysGroupUserRoles.get(i).getUserId());
         }

         queryWrapper.notIn(SysUser::getId, userIds);
      }
      return this.list(queryWrapper);
   }
   private SysUser getByUserName(String userName) {
      LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<SysUser>();
      queryWrapper.eq(SysUser::getUsername, userName);
      return this.getOne(queryWrapper);
   }

   public Map<String, Object> getByUser(String username, String password) {

      if (getByUserName(username) == null) {
         return ResultUtils.getFaildResultData(new String[]{"用户名不存在！"});
      } else {

         String encode = null;

         try {
            encode = Md5Util.md5Encode(username, password);
         } catch (Exception var10) {
            throw new RuntimeException("密码md5解码异常");
         }
         LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<SysUser>();
         queryWrapper.eq(SysUser::getUsername, username);
         queryWrapper.eq(SysUser::getPassword, encode);
         SysUser sysUser = this.getOne(queryWrapper);

         if (sysUser == null) {
            return ResultUtils.getFaildResultData(new String[]{"密码错误，请重新输入！"});
         } else {
            RuleUser ruleUser = new RuleUser();
            BeanUtils.copyProperties(sysUser, ruleUser);
            ruleUser.setPassword("");
            Set<Role> roles = this.getRoles(ruleUser.getId());
            ruleUser.setAuthorities(roles);
            ruleUser.setHasPermissionPatterns(this.getUserUrlPermissions(roles));
            this.userHolder.holdUser(ruleUser);
            Map map = new HashMap();
            map.put("userId", ruleUser.getId());
            return map;
         }
      }
   }

   public void logout() {
      this.userHolder.destroy();
   }

   private Set<String> getUserUrlPermissions(Set<Role> roles) {
      List<String> roleIds = new ArrayList(Collections2.transform(roles, new Function<Role, String>() {
         public String apply(Role input) {
            return input.getRoleId();
         }
      }));
      return new HashSet(Lists.transform(this.roleauthorityService.getUserRoleUrlPermissions(new ArrayList(roleIds)), new Function<RoleResource, String>() {
         public String apply(RoleResource input) {
            return input.getUrl();
         }
      }));
   }

   private Set<Role> getRoles(Long userId) {

      List<RuleUserRole> ruleUserRoles = this.ruleUserRoleService.getListByUserId(userId);
      return new HashSet(Lists.transform(ruleUserRoles, new Function<RuleUserRole, Role>() {
         public Role apply(RuleUserRole input) {
            Role role = new Role();
            role.setRoleId(String.valueOf(input.getRoleId()));
            return role;
         }
      }));
   }
}
